﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using UT3Bots.Communications;


namespace UT3Bots.UTItems
{
	public abstract class UTBotState : UTObject
	{
		//Common State variables
		protected UTVector _rotation;
		protected UTVector _velocity;
		protected string _name;
		protected int _health;
		protected int _armor;
		protected WeaponType _weapon = WeaponType.None;
		protected FireType _firingType;
		protected BotMesh _mesh;
		protected BotColor _colour;




		#region Properties

		/// <summary>
		/// The actual name of this bot
		/// </summary>
		public string Name
		{
			get
			{
				return this._name;
			}
			internal set
			{
				this._name = value;
				OnPropertyChanged("Name");
			}
		}

		/// <summary>
		/// The amount of health this bot has (Between 0 and 200)
		/// </summary>
		public int Health
		{
			get
			{
				return this._health;
			}
			internal set
			{
				this._health = value;
				OnPropertyChanged("Health");
			}
		}

		/// <summary>
		/// The amount of armor this bot has 
		/// </summary>
		public int ArmorStrength
		{
			get
			{
				return this._armor;
			}
			internal set
			{
				this._armor = value;
				OnPropertyChanged("ArmorStrength");
			}
		}

		/// <summary>
		/// The 3D Vector of which way this bot is facing (X, Y, Z = Yaw, Pitch, Roll)
		/// </summary>
		public UTVector Rotation
		{
			get
			{
				return this._rotation;
			}
			internal set
			{
				this._rotation = value;
				OnPropertyChanged("Rotation");
				OnPropertyChanged("RotationAngle");
			}
		}

		/// <summary>
		/// The Angle in degrees of which way this bot is facing from a top down view
		/// </summary>
		public double RotationAngle
		{
			get
			{
				return (this._rotation.Y / 65535d) * 360;
			}
		}


		/// <summary>
		/// The 3D Vector of which direction and how fast this bot is moving
		/// </summary>
		public UTVector Velocity
		{
			get
			{
				return this._velocity;
			}
		}

		/// <summary>
		/// The skinned colour of this bot
		/// </summary>
		public BotColor Color
		{
			get
			{
				return this._colour;
			}
		}


		/// <summary>
		/// The mesh of this bot
		/// </summary>
		public BotMesh Mesh
		{
			get
			{
				return this._mesh;
			}
		}

		/// <summary>
		/// The weapon currently selected by this bot
		/// </summary>
		public WeaponType Weapon
		{
			get
			{
				return this._weapon;
			}
		}

		/// <summary>
		/// Whether this bot is currently not firing, firing or alt-firing
		/// </summary>
		public FireType FiringType
		{
			get
			{
				return this._firingType;
			}
			internal set
			{
				this._firingType = value;
				OnPropertyChanged("FiringType");
				OnPropertyChanged("IsFiring");
			}
		}

		/// <summary>
		/// Is the bot firing
		/// </summary>
		public bool IsFiring
		{
			get
			{
				return this._firingType != FireType.None;
			}
		}
		#endregion



		//Constructor
		internal UTBotState()
			: base(null, null)
		{
		}

		internal UTBotState(UTIdentifier Id, UTVector Location, UTVector Rotation, UTVector Velocity, string Name, int Health, int Armor, WeaponType Weapon, FireType Firing, BotMesh Mesh, BotColor Color)
			: base(Id, Location)
		{
			this._rotation = Rotation;
			this._velocity = Velocity;
			this._name = Name;
			this._health = Health;
			this._armor = Armor;
			this._weapon = Weapon;
			this._firingType = Firing;
			this._mesh = Mesh;
			this._colour = Color;
		}


		internal virtual void UpdateState(Message playerMessage)
		{
			if (playerMessage != null && (playerMessage.Info == InfoMessage.PLAYER_INFO || playerMessage.Info == InfoMessage.SELF_INFO))
			{
				this._id = new UTIdentifier(playerMessage.Arguments[0]);
				this._location = UTVector.Parse(playerMessage.Arguments[1]);
				this._rotation = UTVector.Parse(playerMessage.Arguments[2]);
				this._velocity = UTVector.Parse(playerMessage.Arguments[3]);
				this._name = playerMessage.Arguments[4];
				this._health = int.Parse(playerMessage.Arguments[5]);
				this._armor = int.Parse(playerMessage.Arguments[6]);
				this._weapon = playerMessage.Arguments[7].GetAsWeaponType();
				this._firingType = (FireType)(int.Parse(playerMessage.Arguments[8]));
				this._mesh = (BotMesh)(int.Parse(playerMessage.Arguments[9]));
				this._colour = (BotColor)(int.Parse(playerMessage.Arguments[10]));
			}
		}


	}
}
